import { Enemy } from '../enemy';
import { SCENE_DATA } from '../../data/scene';
import { EVENTS, type IEventBus } from '../../events';
import { EnemyFactory } from '../enemy/enemy-factory';
import {
  REALM_BIG_LEVEL_NUMBER_MAP,
  REALM_BIG_LEVEL_TYPE,
  REALM_LAYER_CONFIG,
  type RealmBigLevelType,
} from '../../data/realm';
import { BaseModel } from '../base';
import { MODEL_NAME } from '../../constants/model-names';
import { RealmReader } from '../realm/realm-reader';
import { SceneReader } from '../../systems/scene/reader';
import type { AuthorInfo } from '../../types';

/** 场景敌人配置接口 */
export interface SceneEnemyConfig {
  /** 敌人配置ID */
  enemyId: string;
  /** 敌人生成权重（用于随机生成） */
  weight?: number;
  /** 最小等级 */
  minLevel?: number;
  /** 最大等级 */
  maxLevel?: number;
  /** 最小大境界 */
  minBigRealm?: RealmBigLevelType;
  /** 最大大境界 */
  maxBigRealm?: RealmBigLevelType;
  /** 最小小境界 */
  minSmallRealm?: number;
  /** 最大小境界 */
  maxSmallRealm?: number;
}

/** 场景配置接口 */
export interface SceneConfig {
  /** 场景唯一标识 */
  id: string;
  /** 场景名称 */
  name: string;
  /** 场景描述 */
  description?: string;
  /** 场景敌人配置列表 */
  enemies: SceneEnemyConfig[];
  /** 玩家推荐境界 */
  recommendedRealm?: RealmBigLevelType;
  /** 玩家推荐等级 */
  recommendedLevel?: number;
  /** 场景遭遇配置 */
  encounter?: {
    /** 最小遭遇间隔（毫秒） */
    minInterval: number;
    /** 最大遭遇间隔（毫秒） */
    maxInterval: number;
    /** 最小敌人数量 */
    minEnemyCount: number;
    /** 最大敌人数量 */
    maxEnemyCount: number;
  };
  /** 作者信息 */
  author?: AuthorInfo;
}

/**
 * 场景类 - 管理单个场景的配置和敌人生成逻辑
 */
export class Scene {
  readonly id: string;
  readonly name: string;
  readonly description?: string;
  readonly enemies: SceneEnemyConfig[];
  readonly recommendedRealm?: RealmBigLevelType;
  readonly recommendedLevel?: number;
  readonly encounterConfig: {
    minInterval: number;
    maxInterval: number;
    minEnemyCount: number;
    maxEnemyCount: number;
  };

  constructor(config: SceneConfig) {
    this.id = config.id;
    this.name = config.name;
    this.description = config.description;
    this.enemies = [...config.enemies];
    this.recommendedRealm = config.recommendedRealm;
    this.recommendedLevel = config.recommendedLevel;

    // 默认遭遇配置
    this.encounterConfig = config.encounter || {
      minInterval: 3 * 1000,
      maxInterval: 5 * 1000,
      minEnemyCount: 1,
      maxEnemyCount: 3,
    };
  }

  getRecommendedRealm(): string {
    return RealmReader.getRealmDisplayName(this.recommendedRealm!);
  }

  /** 获取场景基本信息 */
  getInfo() {
    return {
      id: this.id,
      name: this.name,
      description: this.description,
      recommendedLevel: this.recommendedLevel,
      recommendedRealm: this.getRecommendedRealm(),
      config: SceneReader.getConfigBySceneId(this.id),
    };
  }

  /** 获取敌人配置信息 */
  getEnemyConfigs(): SceneEnemyConfig[] {
    return [...this.enemies];
  }

  /**
   * 获取所有可用的大境界类型（按顺序排列）
   */
  private getAvailableRealmTypes(): RealmBigLevelType[] {
    return Object.entries(REALM_BIG_LEVEL_NUMBER_MAP)
      .sort(([, a], [, b]) => a - b)
      .map(([type]) => type as RealmBigLevelType);
  }

  /**
   * 根据大境界类型获取最大小境界层数
   */
  private getMaxSmallRealmForBigRealm(bigRealmType: RealmBigLevelType): number {
    return REALM_LAYER_CONFIG[bigRealmType] || 4; // 默认4层
  }

  /**
   * 在境界范围内随机选择一个大境界
   */
  private getRandomBigRealmType(
    minBigRealm?: RealmBigLevelType,
    maxBigRealm?: RealmBigLevelType
  ): RealmBigLevelType {
    const allRealms = this.getAvailableRealmTypes();

    // 没有指定境界范围，返回最低境界
    if (!minBigRealm && !maxBigRealm) {
      return REALM_BIG_LEVEL_TYPE.FAN_REN;
    }

    let startIndex = 0;
    let endIndex = allRealms.length - 1;

    // 计算最小境界索引
    if (minBigRealm) {
      const minNumber = REALM_BIG_LEVEL_NUMBER_MAP[minBigRealm];
      startIndex = allRealms.findIndex(
        (realm) => REALM_BIG_LEVEL_NUMBER_MAP[realm] >= minNumber
      );
      if (startIndex === -1) startIndex = 0;
    }

    // 计算最大境界索引
    if (maxBigRealm) {
      const maxNumber = REALM_BIG_LEVEL_NUMBER_MAP[maxBigRealm];
      endIndex =
        allRealms.findIndex(
          (realm) => REALM_BIG_LEVEL_NUMBER_MAP[realm] > maxNumber
        ) - 1;
      if (endIndex === -2) endIndex = allRealms.length - 1;
      if (endIndex < 0) endIndex = allRealms.length - 1;
    }

    // 确保范围有效
    if (startIndex > endIndex) {
      [startIndex, endIndex] = [endIndex, startIndex];
    }

    // 在有效范围内随机选择
    const randomIndex =
      Math.floor(Math.random() * (endIndex - startIndex + 1)) + startIndex;
    return allRealms[randomIndex]!;
  }

  /**
   * 为大境界随机选择小境界
   */
  private getRandomSmallRealmForBigRealm(
    bigRealmType: RealmBigLevelType,
    minSmallRealm?: number,
    maxSmallRealm?: number
  ): number {
    const maxSmallForBigRealm = this.getMaxSmallRealmForBigRealm(bigRealmType);

    let minSmall = minSmallRealm || 1;
    let maxSmall = maxSmallRealm || maxSmallForBigRealm;

    // 确保不超过该大境界的最大层数
    minSmall = Math.max(1, Math.min(minSmall, maxSmallForBigRealm));
    maxSmall = Math.max(1, Math.min(maxSmall, maxSmallForBigRealm));

    // 确保最小值不超过最大值
    if (minSmall > maxSmall) {
      [minSmall, maxSmall] = [maxSmall, minSmall];
    }

    if (minSmall === maxSmall) {
      return minSmall;
    }

    return Math.floor(Math.random() * (maxSmall - minSmall + 1)) + minSmall;
  }

  /**
   * 随机生成遭遇的敌人
   * 根据权重随机选择敌人配置，生成指定数量的敌人实例
   */
  generateEncounter(): Enemy[] {
    const encounteredEnemies: Enemy[] = [];

    if (this.enemies.length === 0) return encounteredEnemies;

    // 随机确定敌人数量
    const { minEnemyCount, maxEnemyCount } = this.encounterConfig;
    const enemyCount =
      Math.floor(Math.random() * (maxEnemyCount - minEnemyCount + 1)) +
      minEnemyCount;

    // 计算总权重用于加权随机
    const totalWeight = this.enemies.reduce(
      (sum, ec) => sum + (ec.weight || 1),
      0
    );

    for (let i = 0; i < enemyCount; i++) {
      // 按权重随机选择敌人配置
      let rand = Math.random() * totalWeight;
      const selected = this.enemies.find(
        (ec) => (rand -= ec.weight || 1) <= 0
      )!;

      let enemyLevel: number;
      if (selected.minLevel != null && selected.maxLevel != null) {
        enemyLevel =
          Math.floor(
            Math.random() * (selected.maxLevel - selected.minLevel + 1)
          ) + selected.minLevel;
      } else if (selected.minLevel != null) {
        enemyLevel = selected.minLevel;
      } else if (selected.maxLevel != null) {
        enemyLevel = Math.floor(Math.random() * selected.maxLevel) + 1;
      } else {
        enemyLevel = this.recommendedLevel || 1;
      }
      enemyLevel = Math.max(1, enemyLevel);

      const realmOptions: any = {};

      // 只在配置中指定了境界范围时才设置境界
      if (selected.minBigRealm || selected.maxBigRealm) {
        // 随机选择大境界
        const bigRealmType = this.getRandomBigRealmType(
          selected.minBigRealm,
          selected.maxBigRealm
        );

        // 随机选择小境界
        const smallRealmLevel = this.getRandomSmallRealmForBigRealm(
          bigRealmType,
          selected.minSmallRealm,
          selected.maxSmallRealm
        );

        realmOptions.realm = {
          bigLevelType: bigRealmType,
          smallLevel: smallRealmLevel,
        };
      }

      try {
        const enemy = EnemyFactory.createEnemy(selected.enemyId, {
          level: enemyLevel,
          ...realmOptions,
        });
        encounteredEnemies.push(enemy);
      } catch (error) {
        console.warn(`创建敌人失败: ${selected.enemyId}`, error);

        // 如果创建失败，尝试使用默认配置创建
        try {
          const fallbackEnemy = EnemyFactory.createEnemy(selected.enemyId, {
            level: enemyLevel,
          });
          encounteredEnemies.push(fallbackEnemy);
        } catch (fallbackError) {
          console.error(
            `备用创建敌人也失败: ${selected.enemyId}`,
            fallbackError
          );
        }
      }
    }
    return encounteredEnemies;
  }

  /** 获取随机遭遇间隔时间（毫秒） */
  getRandomEncounterInterval(): number {
    const { minInterval, maxInterval } = this.encounterConfig;
    return (
      Math.floor(Math.random() * (maxInterval - minInterval + 1)) + minInterval
    );
  }

  /** 添加敌人配置 */
  addEnemyConfig(config: SceneEnemyConfig): void {
    this.enemies.push(config);
  }

  /** 移除敌人配置 */
  removeEnemyConfig(enemyId: string): boolean {
    const index = this.enemies.findIndex((enemy) => enemy.enemyId === enemyId);
    if (index !== -1) {
      this.enemies.splice(index, 1);
      return true;
    }
    return false;
  }

  /**
   * 根据权重获取随机敌人配置（不创建实例）
   */
  getRandomEnemyConfig(): SceneEnemyConfig | null {
    if (this.enemies.length === 0) {
      return null;
    }

    const totalWeight = this.enemies.reduce((sum, enemyConfig) => {
      return sum + (enemyConfig.weight || 1);
    }, 0);

    const randomValue = Math.random() * totalWeight;
    let weightSum = 0;

    for (const enemyConfig of this.enemies) {
      weightSum += enemyConfig.weight || 1;
      if (randomValue <= weightSum) {
        return enemyConfig;
      }
    }

    return this.enemies[0] ?? null;
  }
}

// ==================== SceneManager 类 ====================

/**
 * 场景管理器 - 管理所有场景的注册、切换和遭遇触发
 */
class SceneManager {
  /** 所有注册的场景 */
  private scenes: Map<string, Scene> = new Map();
  /** 当前场景 */
  private currentScene: Scene | null = null;

  constructor() {
    // 初始化时注册所有场景数据
    this.registerScenes(SCENE_DATA);
  }

  /** 注册单个场景 */
  registerScene(config: SceneConfig): void {
    const scene = new Scene(config);
    this.scenes.set(config.id, scene);
  }

  /** 注册多个场景 */
  registerScenes(configs: SceneConfig[]): void {
    configs.forEach((config) => this.registerScene(config));
  }

  /** 根据ID获取场景 */
  getScene(sceneId: string): Scene | null {
    return this.scenes.get(sceneId) || null;
  }

  /** 获取所有场景 */
  getAllScenes(): Scene[] {
    return Array.from(this.scenes.values());
  }

  /** 获取当前场景 */
  getCurrentScene(): Scene | null {
    return this.currentScene;
  }

  /** 切换场景 */
  changeScene(sceneId: string): boolean {
    const targetScene = this.scenes.get(sceneId);
    if (!targetScene) {
      return false;
    }

    // 避免重复切换到同一场景
    if (targetScene.id === this.currentScene?.id) {
      return false;
    }

    this.currentScene = targetScene;
    return true;
  }

  /** 手动触发遭遇（用于调试或特殊事件） */
  triggerManualEncounter(): Enemy[] {
    if (!this.currentScene) {
      return [];
    }

    const enemies = this.currentScene.generateEncounter();
    return enemies;
  }

  /** 获取场景基本信息 */
  getSceneInfo(sceneId: string) {
    const scene = this.getScene(sceneId);
    return scene ? scene.getInfo() : null;
  }

  /** 获取所有场景信息 */
  getAllSceneInfo() {
    return this.getAllScenes().map((scene) => scene.getInfo());
  }

  /** 清理资源 */
  dispose(): void {
    this.scenes.clear();
    this.currentScene = null;
  }
}

/**
 * 场景模型 - 管理场景探索状态和敌人遭遇逻辑
 * 与事件总线集成，负责状态更新和事件触发
 */
export class SceneModel extends BaseModel {
  public name = MODEL_NAME.SCENE;
  private bus: IEventBus;
  private sceneManager: SceneManager;

  /** 探索相关状态 */
  private exploreNeedTime = 0; // 探索需要的时间
  private exploredTime = 0; // 已探索的时间
  private exploreProgress = 0; // 探索进度 (0-1)
  private isExploring = false; // 是否正在探索
  private isAutoExplore = false; // 是否自动探索
  private enemies: Enemy[] = []; // 当前遭遇的敌人

  constructor(bus: IEventBus) {
    super();
    this.bus = bus;
    this.sceneManager = new SceneManager();
  }

  /** 切换场景 */
  public changeScene(sceneId: string) {
    const success = this.sceneManager.changeScene(sceneId);
    if (success) {
      this.bus.emit(EVENTS.SCENE_STATE_UPDATE);
    }
  }

  /** 获取随机遭遇间隔时间 */
  public getRandomEncounterInterval() {
    const currentScene = this.sceneManager.getCurrentScene();
    if (!currentScene) return 0;
    return currentScene.getRandomEncounterInterval();
  }

  /** 手动触发遭遇 */
  public triggerManualEncounter() {
    this.enemies = this.sceneManager.triggerManualEncounter();
  }

  /** 计算探索进度 */
  private calcExploreProgress() {
    const currentProgress = this.exploredTime / this.exploreNeedTime;
    if (currentProgress >= 1) {
      this.exploreProgress = 1;
      return;
    }
    // 只有当进度变化超过1%时才更新，避免频繁触发事件
    if (currentProgress - this.exploreProgress >= 0.01) {
      this.exploreProgress = currentProgress;
    }
  }

  /** 重置探索进度 */
  private resetExploreProgress() {
    this.exploreProgress = 0;
  }

  /**
   * 更新探索时间
   * @param dt 时间增量（秒）
   */
  public updateExploredTime(dt: number) {
    if (!this.isExploring) return;

    this.exploredTime += dt;
    this.calcExploreProgress();

    // 探索完成，触发遭遇
    if (this.exploredTime >= this.exploreNeedTime) {
      this.isExploring = false;
      this.exploredTime = 0;
      this.resetExploreProgress();
      this.enemies = this.sceneManager.triggerManualEncounter();
      this.bus.emit(EVENTS.SCENE_EXPLORE_COMPLETED);
    }

    this.bus.emit(EVENTS.SCENE_STATE_UPDATE);
  }

  /** 开始探索 */
  public startExplore() {
    if (this.isExploring) return;
    this.calcExploreNeedTime();
    this.isExploring = true;
    this.bus.emit(EVENTS.SCENE_STATE_UPDATE);
  }

  /** 开始自动探索 */
  public startAutoExplore() {
    if (this.isAutoExplore) return;
    this.isAutoExplore = true;
    this.startExplore();
  }

  /** 停止探索 */
  public stopExplore() {
    this.exploreNeedTime = 0;
    this.exploredTime = 0;
    this.isExploring = false;
    this.isAutoExplore = false;
    this.enemies = [];
    this.resetExploreProgress();
    this.bus.emit(EVENTS.SCENE_STATE_UPDATE);
  }

  /** 计算探索所需时间 */
  public calcExploreNeedTime() {
    this.exploreNeedTime = this.getRandomEncounterInterval() / 1000;
  }

  /** 获取当前遭遇的敌人 */
  public getEnemies() {
    return this.enemies;
  }

  /** 获取是否自动探索 */
  public getIsAutoExplore() {
    return this.isAutoExplore;
  }

  /** 获取UI状态 */
  public get uiState() {
    return {
      scenes: this.sceneManager.getAllSceneInfo(),
      currentScene: this.sceneManager.getCurrentScene(),
      isExploring: this.isExploring,
    };
  }
}
